package com.swak.ARQ;

import java.util.List;
import java.util.Queue;

import com.swak.reactivex.arq.ARQ;
import com.swak.reactivex.arq.ARQ.Ack;
import com.swak.reactivex.arq.ARQ.Segment;
import com.swak.utils.Lists;
import com.swak.utils.Queues;

import io.netty.buffer.ByteBuf;

/**
 * 编码 ： 解码
 * 
 * @author 618lf
 */
public class SegmentCodec {

	public static List<Segment> ackSegments(ARQ arq) {

		List<Segment> segments = Lists.newArrayList();

		Queue<Ack> acks = Queues.newSpscQueue();
		for (int i = 0; i < 30; i++) {
			acks.add(new Ack().setSn(i).setTs(i));
		}

		for (;;) {
			if (acks.peek() == null) {
				break;
			}

			// buffer 写满 或者 acks 全部写完
			ByteBuf buffer = arq.allotFlushByteBuf();

			// 开始写入的 index.
			for (;;) {
				Ack ack = acks.peek();
				if (ack == null // 没有 ack 的数据
						|| buffer.writableBytes() == 0 // buffer 空间不足
						|| buffer.writableBytes() < ARQ.ACK_MIN_LEN) {// 没法写入开始数据
					break;
				}

				buffer.writeInt((int) ack.getSn());
				buffer.writeInt((int) ack.getTs());
				acks.poll();
			}

			// 创建分片
			Segment data = new Segment(1L);
			data.addOption(Segment.Ack);
			data.setXmit(1);
			int len = buffer.readableBytes();
			data.setBody(buffer.readRetainedSlice(len));
			data.setBodyLen(len);
			data.setHeadLen(len + ARQ.ARQ_HEAD);
			buffer.release();

			segments.add(data);
		}

		return segments;
	}

	public static void main(String[] args) {
		ARQ arq = new ARQ(1L, null);
		List<Segment> segments = ackSegments(arq);
		for (Segment segment : segments) {
			System.out.println(segment);
			ByteBuf buffer = arq.encode(segment);
			System.out.println("#### 解码 ### ");
			Segment segment2 = arq.decode(buffer);
			System.out.println(segment2);
		}
	}
}
